/*--------------------------------------
	GugloPWN
--------------------------------------*/

// stock libs
#include <time.h>
#include <stdio.h>
#include <nds.h>
#include <fat.h>
#include <filesystem.h>

//my classes
#include "map.h"
#include "block.h"
#include "player.h"

#include "sub_screen.h"

//libs from other people
//#include "efs_lib.h"
//#include "nitrofs.h"
#include "memoryStats.h"


#define FILENAME "3d_plat.nds"


void seedrandom();

// FPS calculation. courtest of Owen.
int frameCounter=0;
int loopCounter=0;
int elapsedFrames=0;
int frameold=0;

void vBlank(void){
   ++elapsedFrames;
   ++frameCounter;

   if (frameCounter>=60){
      frameold=loopCounter;
      frameCounter=0;
      loopCounter=0;
   }
}


//keep track of vertex ram usage
int polygon_count;
int vertex_count;



int main() {	

	// Set vBlank callback.
	irqSet(IRQ_VBLANK,vBlank);
	



	// Setup the Main screen for 3D 
	videoSetMode(MODE_0_3D);
	
	//Set Video RAM
	vramSetBankA(VRAM_A_TEXTURE);
	vramSetBankB(VRAM_B_TEXTURE);
	vramSetBankC(VRAM_C_SUB_BG_0x06200000);
	vramSetBankD(VRAM_D_TEXTURE);
	
	
	
	subscrn *subscreen = new subscrn();
	
	
	
	
	//Set up a console to share with my subscreen crap, 
	PrintConsole bottomScreen;
	consoleInit(&bottomScreen, 2,BgType_Text4bpp, BgSize_T_256x256, 0, 1, false, true);
	consoleClear();
	bgSetPriority(bottomScreen.bgId,0);
	//Fix the palette mess that the console does
	BG_PALETTE_SUB[31] = RGB15(31,31,31);
	BG_PALETTE_SUB[47] = RGB15(31,31,31);
	
	

	// initialize the geometry engine
	glInit();
	
	//setup the sub screen for basic printing
	//consoleDemoInit();
	
	
	// enable antialiasing and texture
	//glEnable(GL_ANTIALIAS);
	glEnable(GL_TEXTURE_2D);
	
	//Set outlining
	//glEnable(GL_OUTLINE);
	//glSetOutlineColor (0, RGB15(0, 0, 0));
	
	// setup the rear plane
	glClearColor(5,5,15,31); // BG must be opaque for AA to work
	glClearPolyID(0); // BG must have a unique polygon ID for AA to work
	glClearDepth(0x7FFF);
	

	// Set our viewport to be the same size as the screen
	glViewport(0,0,255,191);

	//Set camera and perspective
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(70, 256.0 / 192.0, 0.1, 100);
	
	gluLookAt(  0.0, 0.0, 0.10,     //camera possition 
				0.15, 0.15, 0.0,    //look at
				0.0, 0.0, 1.0);     //up
					
	//ds specific, several attributes can be set here	
	glPolyFmt(POLY_ALPHA(0) | POLY_CULL_NONE);
	
	//Set the matrix mode to identity
	glMatrixMode(GL_TEXTURE);
	glLoadIdentity();

	
	// Set the current matrix to be the model matrix
	glMatrixMode(GL_MODELVIEW);
	
	
	
	printf("\nInitialize nitroFS... ");
	nitroFSInit(); 
	printf(" success!");
	
	player *p1 = new player();
	p1->loadcharmodel();
	
	//printf("\nProgram deliberately stopped.");
	//while(1); //Stop here forever!
	
	while (1) 
	{
		//Clean up the Console for a new frame worth of error prints!
		consoleClear();
		
		subscreen->draw_subscreen();
		subscreen->update_subscreen();
		
		scanKeys();
		
		glColor3f(1.0f,1.0f,1.0f);
		p1->updateplayer();
		p1->setplayercam();
		//glPolyFmt(POLY_ALPHA(31) | POLY_CULL_NONE | POLY_ID(1)); //Turns on outline
		p1->drawplayer();
		//glPolyFmt(POLY_ALPHA(31) | POLY_CULL_NONE | POLY_ID(0)); //No outline
		//p1->drawplayercolmap();
		p1->drawplaymapcolmap();
		p1->drawplaymap();


//BEGIN OWENS CODE

	while (GFX_STATUS & (1<<27)); // wait until the geometry engine is not busy

	glGetInt(GL_GET_VERTEX_RAM_COUNT, &vertex_count);
	glGetInt(GL_GET_POLYGON_RAM_COUNT, &polygon_count);

	// Clear console... no more of these crazy \x1b[2J codes

    printf("\n\nMemory Statistics:");
    printf("\n\tTotal mem: %i", getMemUsed() + getMemFree());
    float pc_free = (float)getMemFree() / (float)(getMemUsed()+getMemFree()) * 100.0;
    float pc_used = (float)getMemUsed() / (float)(getMemUsed()+getMemFree()) * 100.0;
    printf("\n\tMem Used: %i (%.1f%%)", getMemUsed(), pc_used);
    printf("\n\tMem Free: %i (%.1f%%)", getMemFree(), pc_free);
    printf("\n");

    printf("\nVideo info: Vert Ram = %i", vertex_count);
    printf("\n            Poly Count = %i", polygon_count);

    printf("\n FPS: %i", frameold);

//END OWENS CODE



		
		// flush to screen	
		glFlush(0);
		
		// count the frame.
		loopCounter++;
		
		
		// wait for the screen to refresh
		swiWaitForVBlank();
	}
	
	return 0;
}

void seedrandom()
{
	int hours, seconds, minutes; 
	time_t unixTime = time(NULL);
	struct tm* timeStruct = gmtime((const time_t *)&unixTime);
		
	hours = timeStruct->tm_hour;
	minutes = timeStruct->tm_min;
	seconds = timeStruct->tm_sec;

	int random_seed = hours+seconds+minutes;
	srand(random_seed);
}


